package com.hq.ims.userpc.busservice;

import com.hq.ims.data.entity.*;
import com.hq.ims.data.entityenum.EnumFeedbackPhase;
import com.hq.ims.data.entityenum.EnumReceiveStatus;
import com.hq.ims.data.event.BusInfoNotificationEvent;
import com.hq.ims.data.service.*;
import com.hq.ims.data.utils.WebExpandUtils;
import com.hq.ims.data.vo.BusInfoNotificationMapstruct;
import com.hq.mybatis.base.page.RequestPage;
import com.hq.mybatis.base.page.ReturnPage;
import com.hq.utils.util.BooleanUtils;
import com.hq.utils.util.ListUtils;
import com.hq.utils.util.ObjectUtils;
import com.hq.utils.vo.ReturnVo;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;

/**
 * @author cx
 * @date 2024/11/26 11:21:02
 * @description 经营信息接收Service
 */
@Service
public class BusInfoNotificationService {

    @Resource
    private BaseBusInfoNotificationService baseBusInfoNotificationService;
    @Resource
    private BaseBusiIndustryAssignService baseBusiIndustryAssignService;
    @Resource
    private BaseBusInfoTrackService baseBusInfoTrackService;
    @Resource
    private BaseBusiInfoService baseBusiInfoService;
    @Resource
    private ApplicationContext applicationContext;
    @Resource
    private BaseBusInfoForewarningService baseBusInfoForewarningService;
    @Resource
    private BaseBusForewarningSetService busForewarningSetService;

    /**
     * 经营信息接收-列表查询
     *
     * @param page  分页对象
     * @param param 条件搜索对象
     * @return ReturnVo
     */
    public ReturnVo<ReturnPage<BusInfoNotificationMapstruct.BusInfoNotificationVo>> pageList(RequestPage<BusInfoNotificationMapstruct.BusInfoNotificationVo> page,
                                                                                             BusInfoNotificationMapstruct.PageSearchVo param) {
        param.setCompanyId(WebExpandUtils.getHeadCompanyId());
        baseBusInfoNotificationService.getByPage(page, param);
        return ReturnVo.buildSuccess(page.getReturnPage());
    }

    /**
     * 经营信息接收-详情
     *
     * @param busInfoNotificationId 主键id
     * @return ReturnVo
     */
    public ReturnVo<BusInfoNotificationMapstruct.DetailVo> getDetail(String busInfoNotificationId) {
        BusInfoNotificationMapstruct.DetailVo detailVo = baseBusInfoNotificationService.getDetailVo(busInfoNotificationId);
        if (detailVo.getReceiveStatus().equals(EnumReceiveStatus.UnReceive)) {
            int timeHour = busForewarningSetService.getHourByEnumFeedbackPhase(EnumFeedbackPhase.PairingNotAgree);
            detailVo.setReceiveForewarningEndDate(detailVo.getPushDate().plusHours(timeHour));
        }
        return ReturnVo.buildSuccess(detailVo);
    }

    /**
     * 经营信息-拒收
     *
     * @param rejectionVo 拒收Vo
     * @return ReturnVo
     */
    @Transactional(rollbackFor = Exception.class)
    public ReturnVo<Boolean> rejection(BusInfoNotificationMapstruct.RejectionVo rejectionVo) {
        // 数据校验
        BusInfoNotification busInfoNotification = baseBusInfoNotificationService.getById(rejectionVo.getBusInfoNotificationId());
        ObjectUtils.isNullThrow(busInfoNotification, "经营信息推送数据不存在！");
        BusiInfo busiInfo = baseBusiInfoService.getById(busInfoNotification.getBusiInfoId());
        ObjectUtils.isNullThrow(busInfoNotification, "经营信息数据不存在！");
        // 更新接收表的状态为"已拒绝"
        busInfoNotification.setReceiveStatus(EnumReceiveStatus.Rejection);
        busInfoNotification.setReasonForRejection(rejectionVo.getReasonForRejection());
        busInfoNotification.setHandleDate(LocalDateTime.now());
        baseBusInfoNotificationService.updateById(busInfoNotification);
        // 更新经营信息产业标记状态,查询产业标记推送公司接收情况
        List<BusInfoNotification> list = baseBusInfoNotificationService.lambdaQuery()
                .select(BusInfoNotification::getReceiveStatus)
                .eq(BusInfoNotification::getBusiInfoId, busiInfo.getBusiInfoId())
                .eq(BusInfoNotification::getIndustryMarkId, busInfoNotification.getIndustryMarkId())
                .list();
        //全部拒绝，更新产业标记为拒绝
        boolean allCompanyRejectFlag = list.stream().allMatch(notification -> EnumReceiveStatus.Rejection.getCode() == notification.getReceiveStatus().getCode());
        if (allCompanyRejectFlag) {
            BusiIndustryAssign busiIndustryAssign = new BusiIndustryAssign();
            busiIndustryAssign.setReceiveStatus(EnumReceiveStatus.Rejection);
            baseBusiIndustryAssignService.lambdaUpdate()
                    .eq(BusiIndustryAssign::getBusiInfoId, busiInfo.getBusiInfoId())
                    .eq(BusiIndustryAssign::getIndustryId, busInfoNotification.getIndustryMarkId())
                    .update(busiIndustryAssign);
        }
        // 查询经营信息的产业标记状态
        List<BusiIndustryAssign> busiIndustryAssignList = baseBusiIndustryAssignService.lambdaQuery()
                .select(BusiIndustryAssign::getReceiveStatus)
                .eq(BusiIndustryAssign::getBusiInfoId, busiInfo.getBusiInfoId())
                .list();
        // 如果全部都是"已拒绝",则修改经营信息表的状态为"已拒绝"
        boolean allMatch = busiIndustryAssignList.stream().allMatch(industryAssign -> industryAssign.getReceiveStatus().equals(EnumReceiveStatus.Rejection));
        if (allMatch) {
            // 产业标记全部拒绝时,更新经营信息表的接收状态为"已拒绝"
            busiInfo.setAcceptStatus(EnumReceiveStatus.Rejection);
            baseBusiInfoService.updateById(busiInfo);
        }

        //发布事件
        applicationContext.publishEvent(new BusInfoNotificationEvent(this, busInfoNotification, BusInfoNotificationEvent.COMPANY_REJECTION_EVENT));
        //返回值
        return ReturnVo.buildSuccess(Boolean.TRUE);
    }

    /**
     * 经营信息-接收
     *
     * @param busInfoNotificationId 主键id
     * @return ReturnVo
     */
    @Transactional(rollbackFor = Exception.class)
    public ReturnVo<Boolean> receive(String busInfoNotificationId) {
        // 数据校验
        BusInfoNotification busInfoNotification = baseBusInfoNotificationService.getById(busInfoNotificationId);
        ObjectUtils.isNullThrow(busInfoNotification, "经营信息推送数据不存在！");
        BusiInfo busiInfo = baseBusiInfoService.getById(busInfoNotification.getBusiInfoId());
        ObjectUtils.isNullThrow(busInfoNotification, "经营信息数据不存在！");
        Boolean isExist = baseBusInfoTrackService.lambdaQuery()
                .eq(BusInfoTrack::getBusInfoNotificationId, busInfoNotificationId)
                .count() > 0;
        BooleanUtils.isTrueThrow(isExist, "该经营信息已经接收,不能重复接收!");
        // 将经营信息接收数据添加到跟踪表中
        BusInfoTrack busInfoTrack = new BusInfoTrack();
        busInfoTrack.setBusiInfoId(busInfoNotification.getBusiInfoId());
        busInfoTrack.setIndustryMarkId(busInfoNotification.getIndustryMarkId());
        busInfoTrack.setIndustryMarkName(busInfoNotification.getIndustryMarkName());
        busInfoTrack.setBusInfoNotificationId(busInfoNotification.getBusInfoNotificationId());
        busInfoTrack.setCompanyId(busInfoNotification.getCompanyId());
        busInfoTrack.setCompanyName(busInfoNotification.getCompanyName());
        busInfoTrack.setLastNewFeedbackPhase(EnumFeedbackPhase.ProjectNotDiscussed);
        busInfoTrack.setLastNewFeedbackDate(LocalDateTime.now());
        busInfoTrack.setBusiPersonName(busInfoNotification.getBusiPersonName());
        busInfoTrack.setBusiPersonId(busInfoNotification.getBusiPersonId());
        baseBusInfoTrackService.save(busInfoTrack);
        // 更新接收表的状态为"已接收"
        busInfoNotification.setReceiveStatus(EnumReceiveStatus.Receive);
        busInfoNotification.setHandleDate(LocalDateTime.now());
        baseBusInfoNotificationService.updateById(busInfoNotification);
        // 更新经营信息产业标记状态为已接收
        BusiIndustryAssign busiIndustryAssign = new BusiIndustryAssign();
        busiIndustryAssign.setReceiveStatus(EnumReceiveStatus.Receive);
        baseBusiIndustryAssignService.lambdaUpdate()
                .eq(BusiIndustryAssign::getBusiInfoId, busiInfo.getBusiInfoId())
                .eq(BusiIndustryAssign::getIndustryId, busInfoNotification.getIndustryMarkId())
                .update(busiIndustryAssign);
        // 查询经营信息的产业标记状态
        List<BusiIndustryAssign> busiIndustryAssignList = baseBusiIndustryAssignService.lambdaQuery()
                .select(BusiIndustryAssign::getReceiveStatus)
                .eq(BusiIndustryAssign::getBusiInfoId, busiInfo.getBusiInfoId())
                .list();
        // 如果全部都是"已接收"
        boolean allMatch = busiIndustryAssignList.stream().allMatch(industryAssign -> industryAssign.getReceiveStatus().equals(EnumReceiveStatus.Receive));
        // 则修改经营信息表的状态为"已接收"，否则是"部分接收"
        busiInfo.setAcceptStatus(allMatch ? EnumReceiveStatus.Receive : EnumReceiveStatus.SectionReceive);
        baseBusiInfoService.updateById(busiInfo);

        // 查询该产业标记的经营信息推送给其他公司的“未接收”数据
        List<BusInfoNotification> otherNotificationList = baseBusInfoNotificationService.lambdaQuery()
                .ne(BusInfoNotification::getBusInfoNotificationId, busInfoNotificationId)
                .eq(BusInfoNotification::getBusiInfoId, busInfoNotification.getBusiInfoId())
                .eq(BusInfoNotification::getIndustryMarkId, busInfoNotification.getIndustryMarkId())
                .eq(BusInfoNotification::getReceiveStatus, EnumReceiveStatus.UnReceive)
                .list();
        if (ListUtils.isExistsEle(otherNotificationList)) {
            // 更新接收状态为"已拒绝"，且拒绝理由为“已被其它公司接收”
            otherNotificationList.forEach(notification -> {
                notification.setReceiveStatus(EnumReceiveStatus.Rejection);
                notification.setReasonForRejection("已被其它公司接收!");
                notification.setHandleDate(LocalDateTime.now());
            });
            baseBusInfoNotificationService.updateBatchById(otherNotificationList);
        }

        //发布事件
        applicationContext.publishEvent(new BusInfoNotificationEvent(this, busInfoNotification, BusInfoNotificationEvent.COMPANY_RECEIVE_EVENT));
        //返回值
        return ReturnVo.buildSuccess(Boolean.TRUE);
    }

    /**
     * 指派经营人员
     *
     * @param appointPersonnelVo 指派经营人员参数
     * @return ReturnVo
     */
    @Transactional(rollbackFor = Exception.class)
    public ReturnVo<Boolean> appointPersonnel(BusInfoNotificationMapstruct.AppointPersonnelVo appointPersonnelVo) {
        // 数据校验
        BusInfoNotification busInfoNotification = baseBusInfoNotificationService.getById(appointPersonnelVo.getBusInfoNotificationId());
        ObjectUtils.isNullThrow(busInfoNotification, "经营信息推送数据不存在！");
        // 更新推送表中的经营人员
        busInfoNotification.setBusiPersonId(appointPersonnelVo.getBusiPersonId());
        busInfoNotification.setBusiPersonName(appointPersonnelVo.getBusiPersonName());
        baseBusInfoNotificationService.updateById(busInfoNotification);
        // 更新跟踪表中的经营人员
        BusInfoTrack busInfoTrack = baseBusInfoTrackService.lambdaQuery()
                .eq(BusInfoTrack::getBusInfoNotificationId, busInfoNotification.getBusInfoNotificationId())
                .one();
        busInfoTrack.setBusiPersonId(appointPersonnelVo.getBusiPersonId());
        busInfoTrack.setBusiPersonName(appointPersonnelVo.getBusiPersonName());
        baseBusInfoTrackService.updateById(busInfoTrack);
        // 更新预警表中的经营人员
        BusInfoForewarning busInfoForewarning = baseBusInfoForewarningService.lambdaQuery()
                .eq(BusInfoForewarning::getDataId, busInfoTrack.getBusInfoTrackId())
                .one();
        if (busInfoForewarning != null) {
            busInfoForewarning.setBusiPersonId(appointPersonnelVo.getBusiPersonId());
            busInfoForewarning.setBusiPersonName(appointPersonnelVo.getBusiPersonName());
            busInfoForewarning.setSendMessageUserId(appointPersonnelVo.getBusiPersonId());
            baseBusInfoForewarningService.updateById(busInfoForewarning);
        }
        return ReturnVo.buildSuccess(Boolean.TRUE);
    }

}
